package com.gitee.wsl.time.sequence.sample

import com.gitee.wsl.time.sequence.InstantSequence
import kotlin.time.Instant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
import kotlin.time.Duration.Companion.seconds
import kotlin.time.ExperimentalTime

class EverySecondInstant(
    private val timeZone: TimeZone = TimeZone.UTC,
) : InstantSequence {

    @OptIn(ExperimentalTime::class)
    override fun generateSchedule(start: Instant): Sequence<Instant> {
        return sequence {
            var nextInstant = start
            while (true) {
                nextInstant = nextInstant.getNextAvailableSecond()
                yield(nextInstant)
            }
        }
    }

    @OptIn(ExperimentalTime::class)
    private fun Instant.getNextAvailableSecond(): Instant {
        return this
            .toLocalDateTime(timeZone)
            .nanosecond0()
            .toInstant(timeZone)
            .plus(1.seconds)
    }

    private fun LocalDateTime.nanosecond0(): LocalDateTime {
        return LocalDateTime(
            year = year,
            month = month,
            day = day,
            hour = hour,
            minute = minute,
            second = second,
            nanosecond = 0
        )
    }

    companion object {
//         operator fun invoke(
//            timeZone: TimeZone = TimeZone.UTC,
//        ): EverySecondInstant {
//            return EverySecondInstant(timeZone)
//        }
    }
}

fun InstantSequence.Companion.everySecond(
    timeZone: TimeZone = TimeZone.UTC,
): EverySecondInstant {
    return EverySecondInstant(timeZone)
}